const http = require('http');
const socketIo = require('socket.io');
const express = require('express');
const XLSX = require('xlsx');

// 创建Express应用
const app = express();
const server = http.createServer(app);
const io = socketIo(server);

// 设置静态文件目录
app.use(express.static('public'));
app.use('/node_modules', express.static('node_modules'));

// 导出Excel接口
app.get('/export-excel', (req, res) => {
  try {
    // 准备Excel数据
    const excelData = signInData.map((record) => ({
      'IP地址': record.id,
      '姓名': record.name,
      '签到时间': new Date(record.timestamp).toLocaleString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        hour12: false
      })
    }));

    // 创建工作簿
    const workbook = XLSX.utils.book_new();
    
    // 创建工作表
    const worksheet = XLSX.utils.json_to_sheet(excelData);
    
    // 设置列宽
    const colWidths = [
      { wch: 15 }, // IP地址列
      { wch: 15 }, // 姓名列
      { wch: 20 }  // 签到时间列
    ];
    worksheet['!cols'] = colWidths;
    
    // 将工作表添加到工作簿
    XLSX.utils.book_append_sheet(workbook, worksheet, '签到记录');
    
    // 生成Excel文件缓冲区
    const excelBuffer = XLSX.write(workbook, { 
      type: 'buffer', 
      bookType: 'xlsx' 
    });
    
    // 设置响应头
    const now = new Date();
    const dateStr = now.toLocaleDateString('zh-CN').replace(/\//g, '-');
    const timeStr = now.toLocaleTimeString('zh-CN', {hour12: false}).replace(/:/g, '-');
    const filename = `签到记录_${dateStr}_${timeStr}.xlsx`;
    
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${encodeURIComponent(filename)}`);
    res.setHeader('Content-Length', excelBuffer.length);
    
    // 发送Excel文件
    res.send(excelBuffer);
    
    console.log(`导出Excel文件: ${filename}, 记录数: ${signInData.length}`);
    
  } catch (error) {
    console.error('导出Excel失败:', error);
    res.status(500).json({ error: '导出Excel失败' });
  }
});

// 存储签到数据
let signInData = [];
let activeUsers = 0;

// 获取客户端真实IP地址的函数
function getClientIP(socket) {
  // 尝试从不同的头部获取真实IP
  const forwarded = socket.handshake.headers['x-forwarded-for'];
  const realIP = socket.handshake.headers['x-real-ip'];
  const remoteAddress = socket.handshake.address;
  
  if (forwarded) {
    // x-forwarded-for 可能包含多个IP，取第一个
    return forwarded.split(',')[0].trim();
  }
  
  if (realIP) {
    return realIP;
  }
  
  // 处理IPv6映射的IPv4地址
  if (remoteAddress && remoteAddress.startsWith('::ffff:')) {
    return remoteAddress.substring(7);
  }
  
  return remoteAddress || 'unknown';
}

// WebSocket连接处理
io.on('connection', (socket) => {
  const clientIP = getClientIP(socket);
  console.log('新用户连接:', socket.id, '- IP:', clientIP);
  activeUsers++;
  io.emit('activeUsers', activeUsers);

  // 检查当前IP是否已经签到
  const existingSignIn = signInData.find(signIn => signIn.id === clientIP);
  const hasSignedIn = !!existingSignIn;

  // 发送现有签到数据和当前IP签到状态给新连接的用户
  socket.emit('existingSignIns', signInData);
  socket.emit('signInStatus', { 
    hasSignedIn: hasSignedIn, 
    signInRecord: existingSignIn || null,
    clientIP: clientIP
  });

  // 处理签到事件
  socket.on('signIn', (data) => {
    // 检查该IP是否已经签到
    const existingSignIn = signInData.find(signIn => signIn.id === clientIP);
    
    if (existingSignIn) {
      // 如果已经签到，返回错误信息
      socket.emit('signInError', { 
        message: '该IP地址已经完成签到，无法重复签到',
        existingRecord: existingSignIn
      });
      console.log('重复签到尝试被阻止:', clientIP, '- 姓名:', data.name);
      return;
    }
    
    const signInRecord = {
      id: clientIP, // 使用IP地址作为ID
      name: data.name,
      timestamp: new Date(),
      socketId: socket.id,
      ip: clientIP // 保留IP地址字段
    };
    
    signInData.push(signInRecord);
    console.log('用户签到:', signInRecord);
    
    // 广播签到信息给所有客户端
    io.emit('newSignIn', signInRecord);
    
    // 向签到用户确认签到成功
    socket.emit('signInSuccess', signInRecord);
  });

  // 处理删除单个签到记录
  socket.on('deleteSignIn', function(data) {
    const { id } = data;
    const deleteId = id; // ID现在是IP地址字符串
    
    // 找到并删除指定的签到记录
    const index = signInData.findIndex(signIn => signIn.id === deleteId);
    
    if (index !== -1) {
      signInData.splice(index, 1);
      
      // 广播签到记录删除事件给所有客户端
      io.emit('signInDeleted', deleteId);
      
      console.log(`签到记录已删除: IP=${deleteId}`);
    } else {
      console.log(`未找到要删除的签到记录: IP=${deleteId}`);
    }
  });

  // 处理清空所有签到记录
  socket.on('clearAllSignIns', function() {
    signInData = [];
    
    // 广播清空所有签到记录事件给所有客户端
    io.emit('allSignInsCleared');
    
    console.log('所有签到记录已清空');
  });

  // 处理断开连接事件
  socket.on('disconnect', () => {
    console.log('用户断开连接:', socket.id);
    activeUsers--;
    io.emit('activeUsers', activeUsers);
    
    // 检查是否有用户在断开连接前签到过
    const userSignInIndex = signInData.findIndex(record => record.socketId === socket.id);
    if (userSignInIndex !== -1) {
      const disconnectedUser = signInData[userSignInIndex];
      console.log('断开连接的用户已签到:', disconnectedUser.name);
    }
  });
});

// 启动服务器
const PORT = process.env.PORT || 3001;
server.listen(PORT, () => {
  console.log(`服务器运行在端口 ${PORT}`);
});